package org.cloud.framework.controller;

import net.sf.json.JSONObject;
import org.cloud.framework.ueditor.ActionEnter;
import org.cloud.framework.utils.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.sax.TransformerHandler;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 打包工具
 */
@RestController
public class PackageContoller extends BaseContoroller{

    @Value("${data.file.package}")
    private String packagePath;

    private static String sb = "";
    private static String status = "0";

    IdWorker idWorker = new IdWorker(2);

    //资源列表
    @RequestMapping("showResources")
    @ResponseBody
    public void showResources(HttpServletRequest request, HttpServletResponse response) throws Exception {
        request.getSession().setAttribute("rootPath",packagePath);

        Map<String,String> m = new HashMap<String,String>();
        InputStream aInputStream =  XmlUtils.class.getResourceAsStream("/resources-config.xml");
        List<Map<String, String>> resources = XmlUtils.getResources(aInputStream);
        System.out.println(resources);
        String s = super.formatToJson(resources);
        super.pringWriterToPage(s, "application/json", response);
    }
    //资源编辑类表
    @RequestMapping("showEdieList")
    @ResponseBody
    public void showEdieList(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String nameEn = request.getParameter("nameEn");
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        File file = new File(packagePath + "/editing/"+nameEn);
        File[] files = file.listFiles();
        List<Map<String,String>> lm = new ArrayList<>();
        Map<String,String> m = null;
        for (File f: files) {
            m = new HashMap<>();
            m.put("name",f.getName());
            m.put("create_time",sf.format(f.lastModified()));
            lm.add(m);
        }
        String s = super.formatToJson(lm);
        super.pringWriterToPage(s, "application/json", response);
    }
    //资源字段
    @RequestMapping("showFields")
    @ResponseBody
    public void showFields(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String nameEn = request.getParameter("nameEn");
        InputStream aInputStream =  XmlUtils.class.getResourceAsStream("/resources-config.xml");
        List<Map<String, Object>> fields = XmlUtils.getFields(aInputStream, nameEn);
        String s = super.formatToJson(fields);
        super.pringWriterToPage(s, "application/json", response);
    }
    //百度富文本上传
    @RequestMapping("ueditorController")
    @ResponseBody
    public void controller(HttpServletRequest request,HttpServletResponse response) {
        try {
            response.setContentType("application/json");
            request.setCharacterEncoding( "utf-8" );
            response.setHeader("Content-Type" , "text/html");
            String rootPath = request.getSession().getServletContext().getRealPath("/");
            String a = request.getRequestURI();
            String exec = new ActionEnter(request, rootPath).exec();
            JSONObject jb = JSONObject.fromObject(exec);
            Map map = (Map)jb;
            for (Object key : map.keySet()) {
                String url ="/package"+map.get(key).toString();
                if("url".equals(key)){
                    map.put(key, url);
                }
            }
            exec = JSONObject.fromObject(map).toString();
            PrintWriter writer = response.getWriter();
            writer.write(exec);
            writer.flush();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //附件上传
    @RequestMapping(value="/fileUpload",method = RequestMethod.POST)
    @ResponseBody
    public void fileUpload(HttpServletRequest request, HttpServletResponse response,
                           @RequestParam("file") MultipartFile file) throws Exception {
        HashMap<String, Object> dMap = new HashMap<String, Object>();
        String uuid="";
        String suffix="";
        String path ="";
        boolean flag = false;
        if (file.getSize() > 0) {
            uuid=String.valueOf(idWorker.nextId());
            String fileName = file.getOriginalFilename();
            suffix = fileName.substring(fileName.lastIndexOf("."),fileName.length());
            if(suffix.equalsIgnoreCase(".jpg")
                    || suffix.equalsIgnoreCase(".jpeg")
                    || suffix.equalsIgnoreCase(".gif")
                    || suffix.equalsIgnoreCase(".png")
                    || suffix.equalsIgnoreCase(".bmp")
                    || suffix.equalsIgnoreCase(".tiff")){
                path = "editing/image/";
            }else{
                path = "editing/file/";
            }

            if(packagePath.endsWith("/") || packagePath.endsWith("\\")){
                path = packagePath + path + DateUtils.formatDate(new Date(),"yyyyMMdd");
            }else{
                path = packagePath + "/" + path + DateUtils.formatDate(new Date(),"yyyyMMdd");
            }
            File f = new File(path);
            if(!f.exists()){
                f.mkdirs();
            }
            byte[] bytes = file.getBytes();
            BufferedOutputStream buffStream =
                    new BufferedOutputStream(new FileOutputStream(new File(path + "/" + uuid + suffix)));
            buffStream.write(bytes);
            buffStream.close();
            System.out.println("【文件上传地址】"+path + "/" + uuid + suffix);
            flag = true;
        }
        if (flag == true) {
            if(packagePath.endsWith("/") || packagePath.endsWith("\\")){
                dMap.put("info", (path + "/" + uuid + suffix).replace(packagePath+"editing",""));
            }else{
                dMap.put("info", (path + "/" + uuid + suffix).replace(packagePath+"/editing",""));
            }
        } else {
            dMap.put("info", "error");
        }
        String result = formatToJson(dMap);
        super.pringWriterToPage(result, "application/json", response);
    }
    //编辑保存
    @RequestMapping("save")
    @ResponseBody
    public void save(HttpServletRequest request, HttpServletResponse response) throws Exception {

        HashMap<String, Object> dMap = new HashMap<String, Object>();

        String resourceNameEn = request.getParameter("resourceNameEn");
        String id = request.getParameter("id");

        InputStream aInputStream =  XmlUtils.class.getResourceAsStream("/resources-config.xml");
        List<Map<String, Object>> fields = XmlUtils.getFields(aInputStream, resourceNameEn);
        Map<String, Object> m = new HashMap<>();
        for (int i = 0; i < fields.size(); i++) {
            String name = fields.get(i).get("nameEn").toString();
            String type = fields.get(i).get("type").toString();
            if(type.equals("file") || type.equals("img")){
                String parameter = request.getParameter(name);
                if(parameter != null){
                    parameter = parameter.replace(packagePath+"/editing","");
                }
                m.put(name,parameter);
            }else if(type.equals("richtext")){
                String parameter = request.getParameter(name);
                if(parameter != null){
                    parameter = parameter.replace("src=\""+packagePath.substring(packagePath.lastIndexOf("/"),packagePath.length())+"/editing","src=\"");
                }
                m.put(name,parameter);
            }else{
                String parameter = request.getParameter(name);
                if(parameter != null){
                    parameter = parameter.replace(packagePath+"/editing","");
                }
                m.put(name,parameter);
            }
        }
        m.put("create_time",DateUtils.getDate(DateUtils.getDateTime(),"yyyy-MM-dd HH:mm:ss"));


        String path = packagePath + "/editing/"+resourceNameEn+".xml";
        List<Map<String, Object>> listMap = new ArrayList<>();
        if(new File(path).exists()){
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser parser = factory.newSAXParser();
            ReadXml readXml = new ReadXml("//entities/entity",0,100000,false);
            parser.parse(packagePath+"/editing/"+resourceNameEn+".xml", readXml);
            listMap = readXml.list;
        }

        if(id != null && !"".equals(id)){//是编辑
            for (int i = 0; i < listMap.size(); i++) {
                if(listMap.get(i).get("id").equals(id)){//编辑项目
                    listMap.remove(listMap.get(i));
                    break;
                }
            }
            m.put("id",id);
        }else{//新增
            m.put("id",idWorker.nextId());
        }
        listMap.add(0,m);
        try{
            FileOutputStream out = new FileOutputStream(new File(path));
            TransformerHandler handler = CreateXMLFile.createXML(out);
            CreateXMLFile.writeToXml(handler, listMap);
            CreateXMLFile.closeXml(handler,out);

            dMap.put("result","success");
            dMap.put("msg","保存成功");
        }catch (Exception e){
            dMap.put("result","fail");
            dMap.put("msg","保存失败");
        }
        String s = super.formatToJson(dMap);
        super.pringWriterToPage(s, "application/json", response);
    }

    //编辑资源列表
    @RequestMapping("editList")
    @ResponseBody
    public void editList(HttpServletRequest request, HttpServletResponse response) throws Exception {

        String nameEn = request.getParameter("nameEn");
        String page = request.getParameter("page");


        String path = packagePath + "/editing/"+nameEn+".xml";
        List<Map<String, Object>> listMap = new ArrayList<>();
        int count = 0;
        if(new File(path).exists()){
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser parser = factory.newSAXParser();
            ReadXml readXml = new ReadXml("//entities/entity",(Integer.parseInt(page)-1)*10,10,false);
            parser.parse(packagePath+"/editing/"+nameEn+".xml", readXml);
            listMap = readXml.list;


            //SAXParserFactory factory1 = SAXParserFactory.newInstance();
            //SAXParser parser1 = factory1.newSAXParser();
            ReadXml readXml1 = new ReadXml("//entities/entity",0,100000,false);
            parser.parse(packagePath+"/editing/"+nameEn+".xml", readXml1);
            List<Map<String, Object>> list = readXml1.list;
            count = list.size();

        }

        StringBuffer sb = new StringBuffer();
        int listsize = listMap==null?0:listMap.size();
        sb.append("{\"listsize\":" + listsize + ",");
        sb.append("\"pageSize\":"
                + (int) Math.ceil(Double.valueOf(count) / 10) + ",");
        sb.append("\"result\":" + super.formatToJson(listMap));

        sb.append("}");
        super.pringWriterToPage(sb.toString(), "application/json", response);
    }
    //包列表
    @RequestMapping("packList")
    @ResponseBody
    public void packList(HttpServletRequest request, HttpServletResponse response) throws Exception {

        String page = request.getParameter("page");

        String path = packagePath + "/package";

        File file = new File(path);
        if(!file.exists()){
            file.mkdirs();
        }
        File[] files = file.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                if(name.endsWith(".zip")){
                    return true;
                }
                return false;
            }
        });

        List<Map<String,String>>lm = new ArrayList<>();
        Map<String,String> m = null;
        if((Integer.parseInt(page) - 1)*10 <= files.length){
            for (int i = (Integer.parseInt(page) - 1)*10; i < (Integer.parseInt(page) - 1)*10 + 10; i++) {
                if(i >= files.length){
                    break;
                }
                m = new HashMap<>();
                m.put("name",files[i].getName());
                m.put("create_time",DateUtils.formatDate(new Date(files[i].lastModified()),"yyyy-MM-dd HH:mm:ss"));
                m.put("path",files[i].getAbsolutePath());
                m.put("size",files[i].length()/1024/1024+"MB,"+files[i].length()/1024%1024+"KB");
                if(m != null && !m.isEmpty()){
                    lm.add(m);
                }
            }
        }

        StringBuffer sb = new StringBuffer();

        int listsize = lm==null?0:lm.size();
        sb.append("{\"listsize\":" + listsize + ",");
        sb.append("\"pageSize\":"
                + (int) Math.ceil(Double.valueOf(files.length) / 10) + ",");
        sb.append("\"result\":" + super.formatToJson(lm));

        sb.append("}");

        super.pringWriterToPage(sb.toString(), "application/json", response);
    }

    //编辑资源删除
    @RequestMapping("editDelete")
    @ResponseBody
    public void editDelete(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HashMap<String, Object> dMap = new HashMap<String, Object>();
        String nameEn = request.getParameter("nameEn");
        String id = request.getParameter("id");

        String path = packagePath + "/editing/"+nameEn+".xml";
        List<Map<String, Object>> listMap = new ArrayList<>();
        if(new File(path).exists()){
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser parser = factory.newSAXParser();
            ReadXml readXml = new ReadXml("//entities/entity",0,100000,false);
            parser.parse(packagePath+"/editing/"+nameEn+".xml", readXml);
            listMap = readXml.list;
        }

       flag: for (Map<String, Object> map :listMap) {
            for (String key:map.keySet()) {
                if(key.equalsIgnoreCase("id")){
                    if(map.get(key).equals(id)){
                        listMap.remove(map);
                        break flag;
                    }
                }
            };
            
        }
        try{
            FileOutputStream out = new FileOutputStream(new File(path));
            TransformerHandler handler = CreateXMLFile.createXML(out);
            CreateXMLFile.writeToXml(handler, listMap);
            CreateXMLFile.closeXml(handler,out);
            dMap.put("result","success");
            dMap.put("msg","删除成功");
        }catch (Exception e){
            dMap.put("result","fail");
            dMap.put("msg","删除失败");
        }
        String s = super.formatToJson(dMap);
        super.pringWriterToPage(s, "application/json", response);
    }
    //一键打包
    @RequestMapping("aKeyToPack")
    @ResponseBody
    public void aKeyToPack(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HashMap<String, Object> dMap = new HashMap<String, Object>();

        sb = "";
        status = "0";

        String editPath= packagePath+"/editing";
        String targetPath=packagePath+"/package";
        String sourcePath=packagePath+"/sources";
        String fileName=String.valueOf(idWorker.nextId());
        if(!new File(targetPath).exists()){
            new File(targetPath).mkdirs();
        }
        if(!new File(sourcePath).exists()){
            new File(sourcePath).mkdirs();
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                sb ="开始...";
                try{
                    //压缩
                    System.out.println(">>>正在压缩...");
                    sb = ("正在压缩...");
                    List<String> l = FileTool.directories(editPath);
                    for (int i = 0; i < l.size(); i++ ) {
                        FileTool.zip(l.get(i), targetPath+"/"+fileName+".zip");
                    }
                    System.out.println(">>>压缩完成！正在转移编辑文件...");
                    sb = ("压缩完成！正在转移编辑文件...");
                    //复制到编辑完成文件夹
                    FileTool.copyFolder(editPath,sourcePath+"/"+fileName);
                    System.out.println(">>>转移完成！正在删除编辑文件...");
                    sb = ("转移完成！正在删除编辑文件...");
                    //删除编辑文件夹
                    FileTool.delAllFile(editPath);
                    System.out.println(">>>删除完成！一键打包完成！");
                    sb = ("删除完成！一键打包完成！");
                    status = "1";
                }catch (Exception e){
                    status = "0";
                    sb = ("一键打包出错！");
                }
            }
        }).start();
        dMap.put("result","success");
        dMap.put("msg","启动成功");
        String s = super.formatToJson(dMap);
        super.pringWriterToPage(s, "application/json", response);
    }

    //一键解包
    @RequestMapping("packBar")
    @ResponseBody
    public void packBar(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HashMap<String, Object> dMap = new HashMap<String, Object>();

        dMap.put("result","success");
        dMap.put("msg",sb.toString());
        dMap.put("status",status);
        String s = super.formatToJson(dMap);
        System.out.println(s);
        super.pringWriterToPage(s, "application/json", response);
    }

    //压缩包下载
    @RequestMapping("downloadfile")
    @ResponseBody
    public void downloadfile(HttpServletRequest request,
                             HttpServletResponse response) throws Exception {
            String name = request.getParameter("name");
            String path = packagePath + "/package/"+name;
            if(new File(path).exists()){
                // 设置响应头，控制浏览器下载该文件
                name = new String(name.getBytes("UTF-8"), "ISO-8859-1");
                response.setHeader("content-disposition",
                        "attachment;filename=" + name);
                response.setContentType("application/octet-stream");
                response.setContentType("application/OCTET-STREAM;charset=UTF-8");
                // 读取要下载的文件，保存到文件输入流
                FileInputStream in = new FileInputStream(path);
                // 创建输出流
                OutputStream out = response.getOutputStream();
                // 创建缓冲区
                byte buffer[] = new byte[1024];
                int len = 0;
                // 循环将输入流中的内容读取到缓冲区当中
                while ((len = in.read(buffer)) > 0) {
                    // 输出缓冲区的内容到浏览器，实现文件下载
                    out.write(buffer, 0, len);
                }
                // 关闭文件输入流
                in.close();
                // 关闭输出流
                out.close();
            }
    }

    //一键解包
    @RequestMapping("edit")
    @ResponseBody
    public void edit(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HashMap<String, Object> dMap = new HashMap<String, Object>();

        String nameEn = request.getParameter("nameEn");
        String id = request.getParameter("id");
        InputStream aInputStream =  XmlUtils.class.getResourceAsStream("/resources-config.xml");
        List<Map<String, Object>> fields = XmlUtils.getFields(aInputStream, nameEn);

        String path = packagePath + "/editing/"+nameEn+".xml";
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();
        ReadXml readXml = new ReadXml("//entities/entity",0,100000,false);
        parser.parse(packagePath+"/editing/"+nameEn+".xml", readXml);
        List<Map<String, Object>> listMap = readXml.list;

        //取数据
        Map<String,Object> map = new HashMap<>();
        for (int i = 0; i < listMap.size(); i++) {
            if(id.equals(listMap.get(i).get("id"))){
                map = listMap.get(i);
            }
        }

        for (String key:map.keySet()) {

            for (int i = 0; i < fields.size(); i++) {
                String type = fields.get(i).get("type").toString();
                if(type.equals("file") || type.equals("img")){
                    String nameEn1 = fields.get(i).get("nameEn").toString();
                    if(key.equalsIgnoreCase(nameEn1)){
                        map.put(key,packagePath+"/editing"+map.get(key));
                    }
                }else if(type.equals("richtext")){
                    map.put(key,map.get(key).toString().replace("src=\"/image","src=\""+packagePath.substring(packagePath.lastIndexOf("/"),packagePath.length())+"/editing/image"));
                }
            }
        }
        dMap.put("data",map);
        dMap.put("fields",fields);
        String s = super.formatToJson(dMap);
        System.out.println(s);
        super.pringWriterToPage(s, "application/json", response);
    }
    @RequestMapping("reading")
    @ResponseBody
    public String IoReadImage(String imgName,HttpServletRequest request,HttpServletResponse response) throws IOException {
        String path = request.getParameter("path");
        ServletOutputStream out = null;
        FileInputStream ips = null;
        try {

            String name = path.substring(path.lastIndexOf("/")+1,path.length());
            ips = new FileInputStream(new File(path));
            response.setContentType("multipart/form-data");
            response.setHeader("content-disposition","filename=" + name);
            out = response.getOutputStream();
            //读取文件流
            int len = 0;
            byte[] buffer = new byte[1024 * 10];
            while ((len = ips.read(buffer)) != -1){
                out.write(buffer,0,len);
            }
            out.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            out.close();
            ips.close();
        }
        return null;
    }

}
